package com.froggyware.tadpole.core.impl;

import com.froggyware.tadpole.TadObject;
import com.froggyware.tadpole.util.FileSystem;
import org.apache.commons.io.FileUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.xerial.snappy.SnappyOutputStream;
import sun.rmi.runtime.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * manage the datastore on disk using json
 * User: Steven
 * Date: 09/09/11
 * Time: 18:21
 */
public class JsonDiskDataStore extends AbstractDataStore {

    private final static Logger LOGGER = Logger.getLogger(JsonDiskDataStore.class.getName());



    @Override
    public void write(TadObject t) {


        ObjectMapper mapper = new ObjectMapper();

        String directory = getFileDirectory(t);
        LOGGER.info("Writing to this directory "+directory);

        try {
            if(enableCompression) {
                OutputStream f0 = new FileOutputStream(getObjectFile(t.getId(), directory));
                SnappyOutputStream s = new SnappyOutputStream(f0);
                mapper.writeValue(s,t);
            } else {
                
                mapper.writeValue(getObjectFile(t.getId(), directory),t);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 
     * @param objectId
     * @param clazz
     * @return
     */
    public TadObject read(String objectId, Class clazz) {

        ObjectMapper mapper = new ObjectMapper();

        String directory = getFileDirectory(clazz);

       // System.out.println("classname="+clazz.getName() + " dir="+directory);


        TadObject object = null;
        try {
            object = (TadObject)mapper.readValue(getObjectFile(objectId, directory), clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return object;
    }

    @Override
    public void drop() {
        File root = new File(getRootDirectory());
        try {
            FileUtils.deleteDirectory(root);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
        FileSystem.createDir(new File(getRootDirectory()));
    }

    @Override
    public void delete(String key, Class clazz) {

        String directory = getFileDirectory(clazz);
        File file = getObjectFile(key, directory);
        file.delete();
    }

    private File getObjectFile(String objectId, String directory) {
        return new File(directory + File.separator + objectId +".json");
    }


    @Override
    public List<String> getCollectionNames() {
        File dir = new File(getRootDirectory());
        List<String> collections = new ArrayList<String>();
        // fetch first name element
        File[] files = dir.listFiles();
        if (files != null) {
            for(File file : files) {
                if (file.getName().equals(".")
                        || file.getName().equals("..")
                        || !file.isDirectory()) {
                    continue;
                }

                String name = file.getName();
                collections.add(name);
            }
        }
        return collections;
    }

    @Override
    public List<String> getObjectIds(String collectionName) {
        List<String> ids = new ArrayList<String>();
        File dir = new File(getRootDirectory() + File.separator + collectionName);
        for(File file : dir.listFiles()) {
            if (file.getName().equals(".")
                    || file.getName().equals("..")) {
                 continue;
            }

            // extract key from file
            String name = file.getName();
            String key = name.substring(0, name.indexOf(".json"));
            ids.add(key);

        }
        return ids;
    }
}
